package com.jungle.client;

import com.google.gson.reflect.TypeToken;
import com.jungle.bfi.domain.vo.DataCategoryVo;
import com.jungle.client.vo.DataDefinitionVo;
import com.jungle.bfi.domain.vo.Option;
import com.jungle.client.channel.HttpClient;
import com.jungle.client.vo.NameValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.function.Consumer;

@Slf4j
public class DataDefinitionInfoController implements Initializable {

    @FXML
    private Button applyButton;
    @FXML
    private TextField displayValueField;
    @FXML
    private TextField valueField;
    @FXML
    private TextField titleField;
    @FXML
    private CheckBox sceneCheckBox;
    @FXML
    private CheckBox requiredCheckBox;
    @FXML
    private TextField datasetNameField;
    @FXML
    private TextField datasetValueField;
    @FXML
    private HBox categoryBox;
    @FXML
    private ComboBox<Option> categoryComboBox;

    private Consumer<DataDefinitionVo> consumer;
    private DataDefinitionVo dataDefinitionVo = new DataDefinitionVo();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        log.info("init DataDefinitionInfoController, location:{}", location);
        initData();
        addPropertyListener();
    }

    private void initData() {
        TypeToken<List<DataCategoryVo>> typeToken = new TypeToken<>() {
        };

        HttpClient.getInstance().post("/dataCategory/findAll", "{}").callback(typeToken,
                list -> {
                    if (list != null) {
                        List<Option> options = list.stream().map(vo -> new Option(vo.getName(), vo.getCode())).toList();
                        categoryComboBox.getItems().clear();
                        categoryComboBox.getItems().addAll(options);
                    }
                }
        );
    }

    private void addPropertyListener() {
        titleField.textProperty().addListener((observable, oldValue, newValue) -> {
            dataDefinitionVo.setTitle(newValue);
            applyButton.setDisable(false);
        });

        sceneCheckBox.selectedProperty().addListener((observable, oldValue, newValue) -> {
            dataDefinitionVo.setScenarioFlag(newValue);
            applyButton.setDisable(false);
        });
        requiredCheckBox.selectedProperty().addListener((observable, oldValue, newValue) -> {
            dataDefinitionVo.setRequired(newValue);
            applyButton.setDisable(false);
        });
        datasetValueField.textProperty().addListener((observable, oldValue, newValue) -> {
            dataDefinitionVo.setDatasetId(newValue);
            applyButton.setDisable(false);
        });
        datasetNameField.textProperty().addListener((observable, oldValue, newValue) -> {
            dataDefinitionVo.setDatasetName(newValue);
            applyButton.setDisable(false);
        });
        categoryComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            dataDefinitionVo.setCategory(newValue);
            applyButton.setDisable(false);
        });
    }

    public void loadData(DataDefinitionVo dataDefinitionVo) {
        this.dataDefinitionVo = dataDefinitionVo;
        if (dataDefinitionVo != null) {
            displayValueField.setText(dataDefinitionVo.getName());
            valueField.setText(dataDefinitionVo.getCode());
            titleField.setText(dataDefinitionVo.getTitle());
            sceneCheckBox.setSelected(dataDefinitionVo.isScenarioFlag());
            if (Boolean.TRUE.equals(dataDefinitionVo.isScenarioFlag())) {
                // 业务场景标识，才显示是否必填项
                requiredCheckBox.setVisible(true);
                requiredCheckBox.setSelected(Boolean.TRUE.equals(dataDefinitionVo.getRequired()));
            } else {
                requiredCheckBox.setVisible(false);
                requiredCheckBox.setSelected(false);
            }
            Option option = new Option(dataDefinitionVo.getCategoryName(), dataDefinitionVo.getCategoryValue());
            categoryComboBox.setValue(option);
            datasetNameField.setText(dataDefinitionVo.getDatasetName());
            datasetValueField.setText(dataDefinitionVo.getDatasetId());
        }
        applyButton.setDisable(true);
    }

    public void onActionApply(ActionEvent event) {
        log.info("onActionApply:{}", event);
        com.jungle.bfi.domain.vo.DataDefinitionVo copy = DataDefinitionVo.copy(dataDefinitionVo);
        HttpClient.getInstance().post("/dataDefinition/store", copy).callback(com.jungle.bfi.domain.vo.DataDefinitionVo.class, dataDefinitionPo -> {
            if (dataDefinitionPo != null) {
                // 回定到consumer
                consumer.accept(DataDefinitionVo.from(dataDefinitionPo));
            }
            applyButton.setDisable(true);
        });
    }

    public void addConsumer(Consumer<DataDefinitionVo> consumer) {
        this.consumer = consumer;
    }

    /**
     * 重置表单
     */
    public void reset() {
        displayValueField.setText("");
        valueField.setText("");
        titleField.setText("");
        datasetNameField.setText("");
        datasetValueField.setText("");
        sceneCheckBox.setSelected(false);
        requiredCheckBox.setSelected(false);
        categoryComboBox.setValue(null);

        applyButton.setDisable(true);
    }

    public void onActionSelectDataset(ActionEvent event) {
        log.info("onActionSelectDataset:{}", event);
        try {
            // 显示选择数据集的对话框
            NameValue nameValue = SelectionDialogController.showSelectionDialog();
            if (nameValue != null) {
                datasetNameField.setText(nameValue.getName());
                datasetValueField.setText(nameValue.getValue());
                if (titleField.getText() == null || titleField.getText().isEmpty()) {
                    titleField.setText(nameValue.getName());
                }
            }
        } catch (IOException e) {
            log.error("showSelectionDialog error", e);
        }
    }
}
